home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Programming / Programming Tools / Pascal Demos from Apple / sfgetfile examp / SFSAMPLE.TEXT next >
Encoding:
Text File  |  1985-05-13  |  17.9 KB  |  596 lines  |  [TEXT/ttxt]

  1. {$X-}   {Turn off stack expansion. This is a Lisa concept, not needed on Mac}
  2. {$U-}   {Turn off the Lisa Libraries. This is required by the WorkShop}
  3. {$R-}   {Turn off range checking}
  4.  
  5. Program SFDialogSample;
  6.  
  7. {--   Jeffery J. Bradford,  Macintosh Technical Support, April 1985    }
  8.  
  9. {--  This is a sample program that shows how to write a dialog box with }
  10. {--- a scrollable window. It is similar to SF Get & Put File, but I have}
  11. {--  left out a lot of things like being able to select items and stuff }
  12. {--  you can probably write if you're considering doing something like  }
  13. {--  this. Also the getting the names of files is not included. Look at }
  14. {--  the File Sys example for how to do this.                           }
  15.  
  16.  
  17.  
  18. USES
  19.     {$U Obj/Memtypes  } MemTypes,
  20.     {$U Obj/QuickDraw } QuickDraw,
  21.     {$U Obj/OSIntf    } OSIntf,
  22.     {$U Obj/ToolIntf  } ToolIntf,
  23.     {$U Obj/PackIntf  } PackIntf;
  24.  
  25. CONST
  26. {menu stuff}
  27.     AppleMenu = 256;
  28.     FileMenu  = 257;
  29.     EditMenu  = 258;
  30.     SFMenu    = 259;
  31.  
  32. {window IDs}
  33.     WindResID = 256;       {resource for background window}
  34.     DlogResID = 256;       {resource for the dialog}
  35.     CntlResID = 256;       {resource for the scroll bar}
  36.  
  37. TYPE
  38. {this is useful stuff you might need sometime}
  39.  
  40.     WordStuff = Packed Record
  41.        Case Integer of
  42.          0: (Word: Integer);
  43.          1: (SByte1,SByte0: SignedByte);
  44.          2: (b15,b14,b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0: Boolean)
  45.        End;
  46.  
  47.     CharStuff = Packed Record
  48.          chr3,chr2,chr1,chr0: char;
  49.        End;
  50.  
  51.     LMwordPtr = ^Integer;          {pointer to low memory address}
  52.     LMLongPtr = ^LongInt;          {pointer to low memory address - long}
  53.  
  54.  
  55.  
  56. VAR
  57. {global program stuff}
  58.     Finished:      Boolean;    {used to terminate the program}
  59.     ClockCursor:   CursHandle; {handle to the waiting watch cursor}
  60.  
  61. {Screen stuff}
  62.     DragArea:   Rect;          {holds the area where window can be dragged in}
  63.     GrowArea:   Rect;          {holds the area to which a window's size can change}
  64.     Screen:     Rect;          {holds the screen dimensions}
  65.  
  66. {graphics stuff}
  67.     Circle:     Rect;          {holds the coordinates for the circle}
  68.  
  69. {Window & Dialog pointer stuff}
  70.     GrafWindow:   WindowPtr;   {pointer to the window}
  71.  
  72. {-----------------------------------------------------------------------------
  73.                      end of global variable definition
  74. -----------------------------------------------------------------------------}
  75.  
  76. PROCEDURE DrawBoxInerds;
  77. {this routine draws a line to show scrolling, it could be file names}
  78. Begin
  79.   PenSize(10,10);
  80.   MoveTo(0,0);
  81.   LineTo(125,300);
  82.   PenSize(1,1);         {restore the pensize}
  83. End;
  84.  
  85. {-----------------------------------------------------------------------------}
  86.  
  87. PROCEDURE DrawGrayLine(theDialog: DialogPtr; ItemNo: integer);
  88. {this is the UserItem procedure that draws the gray divider line}
  89. Var
  90.    ItemType: integer;
  91.    theItem:  Handle;
  92.    itsRect:  Rect;
  93. Begin
  94.   GetDItem(theDialog, ItemNo, ItemType, theItem, itsRect);
  95.   FillRect(itsRect, ltGray);
  96. End;
  97.  
  98. {-----------------------------------------------------------------------------}
  99.  
  100. PROCEDURE Scroll_It(SBar: ControlHandle);
  101. Var OldOrig:   integer;
  102.     NewOrig:   integer;
  103.     delta:     integer;
  104.     theBox:    Rect;
  105.     UpDateRgn: RgnHandle;
  106.     TempClip:  RgnHandle;
  107.  
  108. Begin
  109. {get some new region space}
  110.   UpDateRgn := NewRgn;                 {Rgn for use in updateing}
  111.   TempClip  := NewRgn;                 {Rgn for use in restoring the clip}
  112.  
  113. {calculate the amount scrolled}
  114.   OldOrig := GetCRefCon(SBar);             {get the current origin & save it}
  115.   NewOrig := GetCtlValue(SBar);            {get what the new origin should be}
  116.   delta := OldOrig - NewOrig;              {get V diff. between old & new origin}
  117.  
  118. {get the area to scroll}
  119.   SetRect(theBox, 12, 11, 125, 125);       {get the box rect = item rect}
  120.   InSetRect(theBox, 1,1);                  {make scroll box smaller by one pixel}
  121.  
  122. {do the scrolling}
  123.   ScrollRect(theBox, 0, delta, UpDateRgn);  {move pixels up by Vert. diff.}
  124.  
  125. {clip to the update region, & set to new origin}
  126.   GetClip(TempClip);
  127.   SetOrigin(0,NewOrig);                          {move the origin for drawing}
  128.   OffSetRect(UpDateRgn^^.rgnBBox, 0, NewOrig);   {move the clip}
  129.   ClipRect(UpDateRgn^^.rgnBBox);
  130.  
  131. {draw whatever is in the box}
  132.   DrawBoxInerds;
  133.  
  134. {restore the clip, origin & remember the new origin for next scroll}
  135.   SetOrigin(0,0);
  136.   SetClip(TempClip);
  137.   SetCRefCon(SBar, NewOrig);
  138.  
  139. {throw away unneeded things}
  140.   DisposeRgn(tempClip);
  141.   DisposeRgn(UpDateRgn);
  142. End;
  143.  
  144. {-----------------------------------------------------------------------------}
  145.  
  146. PROCEDURE ItemScroll(ScrollBarHdl:ControlHandle; CntlLoc: integer);
  147. {this routine is used to scroll an item at a time}
  148. Var inc: integer;
  149. Begin
  150.   If CntlLoc = inUpButton then inc := -5
  151.   else
  152.   If CntlLoc = inDownButton then inc := +5;
  153.  
  154.   SetCtlValue(ScrollBarHdl, GetCtlValue(ScrollBarHdl) + inc);
  155.   Scroll_It(ScrollBarHdl);
  156. End;
  157.  
  158. {-----------------------------------------------------------------------------}
  159.  
  160. PROCEDURE PageSroll(ScrollBarHdl:ControlHandle; CntlLoc: integer);
  161. {this routine is used to scroll a page at a time}
  162. Var inc: integer;
  163. Begin
  164.   If CntlLoc = inPageUp then inc := GetCtlMin(ScrollBarHdl)
  165.   else
  166.   If CntlLoc = inPageDown then inc := GetCtlMax(ScrollBarHdl);
  167.  
  168.   SetCtlValue(ScrollBarHdl, inc);
  169.   Scroll_It(ScrollBarHdl);
  170. End;
  171.  
  172. {-----------------------------------------------------------------------------}
  173.  
  174. PROCEDURE Scroller(theDialog: DialogPtr);
  175. Var
  176.    BoxScrollBar: ControlHandle;
  177.    mouseLoc:     Point;
  178.    ControlLoc:   integer;
  179.    dummy:        integer;
  180.  
  181. Begin
  182. {get the mouse location- its local to the current Grafport}
  183.   SetPort(theDialog);
  184.   GetMouse(mouseLoc);
  185.  
  186. {find the control part}
  187.   ControlLoc := FindControl(mouseLoc, theDialog, BoxScrollBar);
  188.   If ControlLoc <> 0 then
  189.     Case ControlLoc of
  190.  
  191.       inUpButtom:   dummy:=TrackControl(BoxScrollBar, mouseLoc, @ItemScroll);
  192.       inDownButton: dummy:=TrackControl(BoxScrollBar, mouseLoc, @ItemScroll);
  193.       inPageUp:     PageSroll(BoxScrollBar, ControlLoc);
  194.       inPageDown:   PageSroll(BoxScrollBar, ControlLoc);
  195.       inThumb:      If TrackControl(BoxScrollBar, mouseLoc, Nil) <> 0 then
  196.                     Scroll_It(BoxScrollBar);
  197.     End
  198.     else sysbeep(3);
  199.  
  200. End;
  201.  
  202. {-----------------------------------------------------------------------------}
  203.  
  204. PROCEDURE BoxContents(theDialog: DialogPtr; ItemNo: integer);
  205. {this procedure draws the box rect and the diagonal line that scrolls}
  206. Var
  207.    ItemType: integer;
  208.    ItemHdl:  Handle;
  209.    ItemRect: Rect;
  210.    LongHdl:  LongInt;
  211.    TempClip: RgnHandle;
  212.  
  213. Begin
  214. {first get the Box size}
  215.   GetDItem(theDialog, ItemNo, ItemType, ItemHdl, ItemRect);
  216.  
  217. {set the clip for drawing}
  218.   TempClip := NewRgn;
  219.   GetClip(TempClip);
  220.   ClipRect(ItemRect);
  221.  
  222. {do the drawing}
  223.   FrameRect(ItemRect);
  224.   DrawBoxInerds;
  225.  
  226. {restore the clip & clean up}
  227.   SetClip(TempClip);
  228.   DisposeRgn(tempClip);
  229.  
  230. End;
  231.  
  232. {-----------------------------------------------------------------------------}
  233.  
  234. PROCEDURE DialogWithWindow;
  235. {this procedure works just (almost) like the standard SFGetFile}
  236. {it does not have the disk checking, etc. that SFGet does}
  237. Var
  238.    SFFileDlg: DialogPtr;
  239.    ItemHit:    integer;
  240.    ItemType:   integer;
  241.    ItemHdl:    Handle;
  242.    ItemRect:   Rect;
  243.    BoxScrollBar:  ControlHandle;
  244.  
  245. Begin
  246. {create the dialog}
  247.   SFFileDlg := GetNewDialog(DlogResID, Nil, Pointer(-1));
  248.   SetPort(SFFileDlg);   {so things work before we go into modal dialog}
  249.  
  250. {set the scroll bar and put it in dialog window; same location as UserItem #7}
  251.   BoxScrollBar := GetNewControl(CntlResID, SFFileDlg);
  252.   SetCtlMin(BoxScrollBar, 0);
  253.   SetCtlMax(BoxScrollBar, 300 - 114);            {114=len of box}
  254.  
  255. {Set scrollbar refCon = origin = to zero initially,don't have to use globals}
  256.   SetCRefCon(BoxScrollBar, 0);
  257.  
  258. {set the gray line userItem}
  259.   GetDItem(SFFileDlg, 6, ItemType, ItemHdl, ItemRect);
  260.   ItemHdl := Handle(ORD(@DrawGrayLine));       {convert procedure name to handle}
  261.   SetDItem(SFFileDlg, 6, ItemType, ItemHdl, ItemRect);
  262.  
  263. {set the diagonal line drawing proc for the Box UserItem}
  264.   GetDItem(SFFileDlg, 4, ItemType, ItemHdl, ItemRect);
  265.   ItemHdl := Handle(ORD(@BoxContents));     {convert procedure name to handle}
  266.   SetDItem(SFFileDlg, 4, ItemType, ItemHdl, ItemRect);
  267.  
  268. {everything has been setup, show the dialog window}
  269.   ShowWindow(SFFileDlg);
  270.  
  271. {now start processing some user inputs}
  272.   Repeat
  273.     ModalDialog(Nil, ItemHit);
  274.     Case ItemHit of
  275.       1: begin end;                             {open}
  276.       2: begin end;                             {cancel}
  277.       3: begin end;                             {flower}
  278.       4: begin end; {SFClick to detect click}   {window}
  279.       5: Scroller(SFFileDlg);                   {scrollBar}
  280.     End;
  281.   Until ItemHit = Cancel;
  282.  
  283.   DisposeControl(BoxScrollBar);
  284.   DisposDialog(SFFileDlg);
  285. End;
  286.  
  287. {-----------------------------------------------------------------------------}
  288.  
  289. PROCEDURE DisplayCircle;
  290. {This procedure is used to draw a circle in a window. Simple}
  291. Begin
  292.   FrameOval(Circle);
  293. End;
  294.  
  295. {-----------------------------------------------------------------------------}
  296.  
  297. PROCEDURE ReSizeWindow(theWindow:WindowPtr; MouseLoc: Point);
  298.  
  299.  Var NewSize: LongInt;
  300.      Width:   Integer;
  301.      Height:  Integer;
  302.  
  303.  Begin
  304.    NewSize := GrowWindow(theWindow,      { grow this window}
  305.                          MouseLoc,       { mouse location  }
  306.                          GrowArea);      { limits of growth - global var}
  307.    If NewSize <> 0 then
  308.    begin
  309.      Height :=  HiWord(NewSize);         {high word of..}
  310.      Width  :=  LoWord(NewSize);         {low word of...}
  311.  
  312.      If Height< 16 then Height := 16; {don't let the window close on itself}
  313.      If Width < 16 then Width  := 16;
  314.  
  315. {now set the new size}
  316.      SizeWindow(theWindow,   {resize this Window}
  317.                     Width,   {set the width}
  318.                    Height,   {set the height}
  319.                     TRUE);   {set the update flag}
  320.  
  321.      InValRect(theWindow^.PortRect); {just inval everything, its a simple draw}
  322.  
  323.    end; {if size of window was changed}
  324.  End;
  325.  
  326. {-----------------------------------------------------------------------------}
  327.  
  328. PROCEDURE ProcessMenu_in(CodeWord:longint);
  329. Var
  330.   Menu_No:    integer;        {menu number that was selected}
  331.   Item_No:    integer;        {item in menu that was selected}
  332.   NameHolder: Str255;         {name holder for desk accessory or font}
  333.   DNA:        integer;        {OpenDA will never return 0, so don't care}
  334.  
  335. Begin
  336.   If CodeWord <> 0 then {go ahead and process the command}
  337.   begin
  338.     Menu_No := HiWord(CodeWord);   {get the Hi word of...}
  339.     Item_no := LoWord(CodeWord);   {get the Lo word of...}
  340.  
  341.     Case Menu_No of
  342.  
  343.      AppleMenu: Begin
  344.                   GetItem(GetMHandle(AppleMenu), Item_No, NameHolder);
  345.                   DNA := OpenDeskAcc(NameHolder);
  346.                 End;
  347.  
  348.       FileMenu: Begin
  349.                   Case Item_No of
  350.                     1: Finished := True;          {quit}
  351.                   End;
  352.                 End;
  353.  
  354.       EditMenu: Begin
  355.                   If Not SystemEdit(Item_no - 1) {if not for a desk accessory}
  356.                   then
  357.                     Case Item_No of
  358.                       1: begin end;               {undo}
  359.                     { 2:                           line divider}
  360.                       3: begin end;               {cut}
  361.                       4: begin end;               {copy}
  362.                       5: begin end;               {paste}
  363.                       6: begin end;               {clear}
  364.                     End;
  365.                 End;
  366.  
  367.        SFMenu: If Item_no = 1 then DialogWithWindow;
  368.  
  369.     End;{case of Menu_No}
  370.  
  371.     HiliteMenu(0);               {unhilite after processing menu}
  372.   end; {the If codeword <> 0}
  373. End; {of ProcessMenu_in procedure}
  374.  
  375.  
  376. {-------------------------------------------------------------------}
  377. {----- These are procedures called from the main event loop  -------}
  378.  
  379. PROCEDURE DealwthMouseDowns(Event:EventRecord);
  380. Var Location: integer;
  381.     WindowPointedTo: WindowPtr;
  382.     MouseLoc:Point;
  383.     WindoLoc:integer;
  384. Begin
  385.   MouseLoc := Event.Where;
  386.   WindoLoc := FindWindow(MouseLoc, WindowPointedTo);
  387.   Case WindoLoc of
  388.  
  389.      inMenuBar: ProcessMenu_in(MenuSelect(MouseLoc));
  390.  
  391.      inSysWindow: SystemClick(Event,WindowPointedTo);
  392.  
  393.      inContent: If WindowPointedTo <> FrontWindow
  394.                 then SelectWindow(WindowPointedTo)
  395.                 else begin {do something} end;
  396.  
  397.      inGrow:    If WindowPointedTo <> FrontWindow
  398.                 then SelectWindow(WindowPointedTo)
  399.                 else ReSizeWindow(WindowPointedTo,MouseLoc);
  400.  
  401.      inDrag   :DragWindow(WindowPointedTo,MouseLoc,DragArea);
  402.  
  403.      inGoAway :If TrackGoAway(WindowPointedTo,MouseLoc)
  404.                then DisposeWindow(WindowPointedTo); {since W mgr allocated space}
  405.  
  406.   End{ of case};
  407. End;
  408.  
  409. {-----------------------------------------------------------------------------}
  410.  
  411. PROCEDURE DealwthKeyDowns(Event:EventRecord);
  412. Var CharCode:char;
  413. Begin
  414.    CharCode:= CharStuff(Event.message).Chr0; {get low byte w/no processing}
  415.  
  416.   If BitAnd(Event.modifier,CmdKey) = CmdKey
  417.    then
  418.      begin  {key board command - probably a menu command}
  419.        ProcessMenu_in(MenuKey(CharCode));
  420.      end
  421.    else
  422.      begin
  423.        {regular keyboard entry}
  424.      end;
  425. End;
  426.  
  427. {-----------------------------------------------------------------------------}
  428.  
  429. PROCEDURE DealwthActivates(Event: EventRecord);
  430. Var TargetWindow:WindowPtr;
  431. Begin
  432.    TargetWindow := WindowPtr(Event.message);
  433.    DrawGrowIcon(TargetWindow);
  434.  
  435.    If Odd(Event.modifiers) {then the window is becoming active}
  436.    then
  437.      begin
  438.        SetPort(TargetWindow);
  439.        {and activate whatever else you need}
  440.        {the scroll bars}
  441.        {hilite selected text}
  442.      end
  443.    else
  444.      begin
  445.        {deactivate whatever you need}
  446.        {deactivate the scroll bars}
  447.        {UNhilite selected text}
  448.      end;
  449. End;
  450.  
  451. {-----------------------------------------------------------------------------}
  452.  
  453. PROCEDURE DealwthUpdates(Event:EventRecord);
  454. Var UpDateWindow,
  455.           TempPort: WindowPtr;
  456. Begin
  457.    UpDateWindow := WindowPtr(Event.message);
  458.    GetPort(TempPort);                {Save the current port}
  459.  
  460.    SetPort    (UpDateWindow);      {set the port to one in Evt.msg}
  461.    BeginUpDate(UpDateWindow);
  462.      EraseRect(UpDateWindow^.VisRgn^^.rgnBBox);
  463.      DisplayCircle;
  464.      DrawGrowIcon(UpDateWindow);
  465.    EndUpDate  (UpDateWindow);
  466.  
  467.    SetPort    (TempPort);             {restore to the previous port}
  468. End;
  469.  
  470. {-----------------------------------------------------------------------------}
  471.  
  472. PROCEDURE MainEventLoop;
  473. Var Event:EventRecord;
  474.     ProcessIt: Boolean;
  475. Begin
  476.   Repeat
  477.     SystemTask;             {so you can support Desk Accessories}
  478.  
  479.     ProcessIt := GetNextEvent(EveryEvent,Event);
  480.     If ProcessIt{is true} then {we'll ProcessIt}
  481.           Case Event.what of
  482.  
  483.             mouseDown  : DealwthMouseDowns(Event);
  484.             KeyDown    : DealwthKeyDowns  (Event);
  485.             ActivateEvt: DealwthActivates (Event);
  486.             UpDateEvt  : DealwthUpdates   (Event);
  487.  
  488.           End;{of Case}
  489.   Until Finished; {terminate the program}
  490. End;
  491.  
  492. {-----------------------------------------------------------------------------}
  493.  
  494. PROCEDURE InitThings;
  495. Begin
  496.   InitGraf(@thePort);          {create a grafport for the screen}
  497.  
  498.   MoreMasters;                 {extra pointer blocks at the bottom of the heap}
  499.   MoreMasters;                 {this is 5 X 64 master pointers}
  500.   MoreMasters;
  501.   MoreMasters;
  502.   MoreMasters;
  503.  
  504. {get the cursors we use and lock them down - no clutter}
  505.   ClockCursor := GetCursor(watchCursor);
  506.   HLock(Handle(ClockCursor));
  507.  
  508. {show the watch while we wait for inits & setups to finish}
  509.   SetCursor(ClockCursor^^);
  510.  
  511. {init everything in case the app is the Startup App}
  512.   InitFonts;                     {startup the fonts manager}
  513.   InitWindows;                   {startup the window manager}
  514.   InitMenus;                     {startup the menu manager}
  515.   TEInit;                        {startup the text edit manager}
  516.   InitDialogs(Nil);              {startup the dialog manager}
  517.  
  518.   Finished := False;             {set program terminator to false}
  519.   FlushEvents(everyEvent,0);     {clear events from previous program}
  520. End;
  521.  
  522. {-----------------------------------------------------------------------------}
  523.  
  524. PROCEDURE SetupLimits;
  525. Begin
  526.   Screen := ScreenBits.Bounds;   {set the size of the screen}
  527.   SetRect(DragArea,Screen.left+4,Screen.top+24,Screen.right-4,Screen.bottom-4);
  528.   SetRect(GrowArea,Screen.left,Screen.top+24,Screen.right,Screen.bottom);
  529. End;
  530.  
  531. {-----------------------------------------------------------------------------}
  532.  
  533. PROCEDURE SetupMenus;
  534. Var
  535.   MenuTopic: MenuHandle;
  536. Begin
  537.   MenuTopic := GetMenu(AppleMenu);  {get the apple desk accessories menu}
  538.   AddResMenu(MenuTopic,'DRVR');     {adds all names into item list}
  539.   InsertMenu(MenuTopic,0);          {put in list held by menu manager}
  540.  
  541.   MenuTopic := GetMenu(FileMenu);   {always need this for Quiting}
  542.   InsertMenu(MenuTopic,0);
  543.  
  544.   MenuTopic := GetMenu(EditMenu);   {always need for editing Desk Accessories}
  545.   InsertMenu(MenuTopic,0);
  546.  
  547.   MenuTopic := GetMenu(SFMenu);     {this is for showing SF sample dialog}
  548.   InsertMenu(MenuTopic,0);
  549.  
  550.   DrawMenuBar;           {all done so show the menu bar}
  551. End;
  552.  
  553. {-----------------------------------------------------------------------------}
  554.  
  555. PROCEDURE SetupWindows;
  556. Begin
  557.   GrafWindow := GetNewWindow(WindResID, Nil, Pointer(-1));
  558. End;
  559.  
  560. {-----------------------------------------------------------------------------}
  561.  
  562. PROCEDURE SetupGraphics;
  563. {used just to show something on the screen}
  564. Begin
  565.   SetRect(Circle, 50,50,100,100);
  566. End;
  567.  
  568. {-----------------------------------------------------------------------------}
  569.  
  570. PROCEDURE SetUpThings;
  571. Begin
  572.   SetupWindows;         {do first so its low in heap}
  573.   SetupMenus;
  574.   SetupLimits;
  575.   SetupGraphics;
  576.  
  577.   InitCursor;           {ready, set, go, show the Arrow cursor}
  578. End;
  579.  
  580. {-----------------------------------------------------------------------------}
  581.  
  582. PROCEDURE CloseThings;
  583. Begin
  584. {close files, if you changed sys resources, UNchange them here be carefull}
  585. {about changing sys things, remember the Switcher could be around}
  586. End;
  587.  
  588. {-----------------------------------------------------------------------------}
  589.  
  590. BEGIN
  591.   InitThings;
  592.   SetUpThings;
  593.   MainEventLoop;
  594.   CloseThings;
  595. END.
  596.